﻿package com.d4p.util
{
	import com.greensock.TweenMax;
	import com.greensock.easing.Circ;
	
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	public class DragThrow extends MovieClip
	{
		private var __stage:Stage;
		
		private var __contentMC:MovieClip;
		private var __counterHolderMC:MovieClip;
		private var __currentCounterMC:MovieClip;
		private var __counterMC:Class;
		
		private var __counters:Array	= [];
		
		private var __w:Number			= 0;	
		private var __h:Number			= 0;
		
		private var __current:int		= 0;		// current portion of the content in view
		private var __posX:Number		= 0;		// x position of the content movie
		private var __prevX:Number		= 0;		// previous x position for velocity tracking
		private var __velX:Number		= 0;		// velocity for tracking if we should move to a new screen
		private var __maxVelX:Number	= 30;		// max velocity speed before we can move to a new screen
		private var __total:uint		= 0;		// total number of screens to scroll along
		private var __minAlpha:Number	= .4;
		
		
		public function DragThrow() {}
		public function setup():void
		{
			reset();
			
			contentMC.buttonMode	= true;
			contentMC.mouseChildren	= false;
			contentMC.addEventListener( MouseEvent.MOUSE_DOWN, trackContentDrag );
			contentMC.addEventListener( MouseEvent.MOUSE_UP, trackContentThrow );
			theStage.addEventListener( MouseEvent.MOUSE_UP, trackContentThrow );
			
			createCounter();
		}
		
		
		
		// RESET CONTENT AND POSITIONS
		public function reset():void
		{
			contentMC.removeEventListener( MouseEvent.MOUSE_DOWN, trackContentDrag );
			contentMC.removeEventListener( MouseEvent.MOUSE_UP, trackContentThrow );
			theStage.removeEventListener( MouseEvent.MOUSE_UP, trackContentThrow );
			
			if (__current != 0)
			{
				__current	= 0;
				getSection(false);
			}
		}
		
		
		// ______________________________________________
		// PRIVATE
		

		private function trackContentDrag(e:MouseEvent):void
		{
			TweenMax.killTweensOf(contentMC);
			contentMC.startDrag(false, new Rectangle(-contentMC.width, 0, contentMC.width+__w, 0));
			contentMC.addEventListener( Event.ENTER_FRAME, trackContentPos );
		}
		

		private function trackContentThrow(e:MouseEvent):void
		{
			contentMC.stopDrag();
			contentMC.removeEventListener( Event.ENTER_FRAME, trackContentPos );
			
			if (__velX >= __maxVelX)		prevSection();
			else if (__velX <= -__maxVelX)	nextSection();
			else
			{
				if (__posX > -((__current*__w) - __w/2))		prevSection();
				else if (__posX < -((__current*__w) + __w/2))	nextSection();
				else											getSection();
			}
		}
		

		private function trackContentPos(e:Event):void
		{
			__velX		= contentMC.parent.mouseX - __prevX;
			__posX		= contentMC.x;
			__prevX		= contentMC.parent.mouseX;
		}
		
		

		private function nextSection():void
		{

			__current++;
			if (__current == total) __current = total-1;
			getSection();
		}

		private function prevSection():void
		{

			__current--;
			if (__current <= 0) __current = 0;
			getSection();
		}
		

		private function getSection(animate:Boolean=true):void
		{
			var newPosX:Number	= -(__current*__w);
			
			if (animate)	TweenMax.to(contentMC, .5, { x: newPosX, ease: Circ.easeOut });
			else			contentMC.x = newPosX;

			__posX	= newPosX;
			__velX	= 0;
			
			updateCounter();
		}
		

		private function createCounter():void
		{

			__counters	= [];
			
			cleanup(counterHolderMC);
			
			for (var i:uint=0; i<total; i++)
			{
				var MC:MovieClip	= new counterMC();
				
				// mouse events
				MC.buttonMode		= true;
				MC.addEventListener( MouseEvent.MOUSE_DOWN, jumpToCounter );
				
				// set props
				if (i > 0)	MC.alpha = __minAlpha;
				else		__currentCounterMC = MC;
				MC.x		= i*10;
				MC.num		= i;
				
				// add to array and display
				__counters.push(MC);
				counterHolderMC.addChild(MC);
			}
			
			// center counter
			counterHolderMC.x	= -(counterHolderMC.width/2);
		}
		
		
		private function jumpToCounter(e:MouseEvent):void
		{
			var MC:MovieClip	= MovieClip(e.currentTarget);
			
			// update current selection
			__current			= MC.num;
			getSection();
		}
		
		
		private function updateCounter():void
		{
			if (__currentCounterMC != null) __currentCounterMC.alpha = __minAlpha;
			__currentCounterMC	= __counters[__current];
			__currentCounterMC.alpha	= 1;
		}
		
		
		private function cleanup(MC:MovieClip):void
		{
			var total:uint	= MC.numChildren;
			for (var i:uint=0; i<total; i++) MC.removeChildAt(0);
		}
		
		
		// ______________________________________________
		// GETTERS & SETTERS
		
		public function get theStage():Stage
		{
			return __stage;
		}
		
		public function set theStage(s:Stage):void
		{
			__stage = s;
		}
		
		public function set contentMC(MC:MovieClip):void
		{
			__contentMC = MC;
		}
		
		public function get contentMC():MovieClip
		{
			return __contentMC;
		}
		
		public function set counterHolderMC(MC:MovieClip):void
		{
			__counterHolderMC = MC;
		}
		
		public function get counterHolderMC():MovieClip
		{
			return __counterHolderMC;
		}
		
		public function set counterMC(c:Class):void
		{
			__counterMC = c;
		}
		
		public function get counterMC():Class
		{
			return __counterMC;
		}
		
		public function set total(n:int):void
		{
			__total = n;
		}
		
		public function get total():int
		{
			return __total;
		}
		
		override public function set width(n:Number):void
		{
			__w = n;
		}
		
		override public function get width():Number
		{
			return __w;
		}
		
		override public function set height(n:Number):void
		{
			__h = n;
		}
		
		override public function get height():Number
		{
			return __h;
		}
	}
}